
#include <vector>
#include <set>

class OneRow
{
public:
    OneRow(int *in, int col, int sort_by_col):m_sort_by_col(sort_by_col)
    {
        for (int i = 0; i < col; ++i)
        {
            m_row.push_back(*in);
            ++in;
        }
    }

    OneRow &operator = (const OneRow &lsh)
    {
        this->m_sort_by_col = lsh.m_sort_by_col;
        this->m_row = lsh.m_row;
        return *this;
    }

    bool operator == (const OneRow &lsh) const
    {
        if (this->m_row.size() != lsh.m_row.size())
        {
            return false;
        }
        
        if (this->m_row[m_sort_by_col] != lsh.m_row[m_sort_by_col])
        {
            return false;
        }

        for (int i = 0; i < this->m_row.size(); ++i)
        {
            if (this->m_row[i] != lsh.m_row[i])
            {
                return false;
            }
        }
        
        return true;
    }

    bool operator != (const OneRow &lsh) const
    {
        return !operator==(lsh);
    }

    bool operator < (const OneRow &lsh) const 
    {
        if (this->m_row[m_sort_by_col] < lsh.m_row[m_sort_by_col])
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    void out(int *out) const
    {
        for (auto it = m_row.begin(); it != m_row.end(); ++it)
        {
            *out = *it;
            ++out;
        }
        
    }

private:
    int m_sort_by_col;
    std::vector<int> m_row;
};


bool sortByCol(int *matrix, int row, int col, int sort_by_col)
{
    if ((matrix == nullptr) 
     || (row < 2) 
     || (col < 1) 
     || (row * col > 1024*1024*1024)  // TODO: Magic Number
     || (sort_by_col >= col))
    {
        return false;
    }
    
    std::set<OneRow> sort_obj;

    int * input = matrix;
    for (int i = 0; i < row; i++)
    {
        OneRow oneObj(input, col, sort_by_col-1);
        sort_obj.insert(oneObj);
        input += col;
    }
    
    int * output = matrix;
    for (auto it = sort_obj.begin(); it != sort_obj.end() ; ++it)
    {
        (*it).out(output);
        output += col;
    }

    return true;
}
